package parse

import (
	"errors"
	"fmt"
	"io"
	"net/url"

	"gitee.com/CH00SE1/download-m3u8-go/tool"
)

type Result struct {
	URL  *url.URL
	M3u8 *M3u8
	Keys map[int]string
}

func FromURL(link string) (*Result, error) {
	u, err := url.Parse(link)
	if err != nil {
		return nil, fmt.Errorf("failed to parse URL '%s': %w", link, err)
	}

	// 验证URL是否有效
	if u.Scheme != "http" && u.Scheme != "https" {
		return nil, fmt.Errorf("unsupported URL scheme: %s", u.Scheme)
	}
	if u.Host == "" {
		return nil, fmt.Errorf("invalid URL: missing host")
	}

	link = u.String()
	body, err := tool.Get(link)
	if err != nil {
		return nil, fmt.Errorf("request m3u8 URL failed: %w", err)
	}
	// noinspection GoUnhandledErrorResult
	defer body.Close()

	m3u8, err := parse(body)
	if err != nil {
		return nil, fmt.Errorf("failed to parse m3u8 content: %w", err)
	}

	// 检查是否为主播放列表
	if len(m3u8.MasterPlaylist) != 0 {
		if len(m3u8.MasterPlaylist) == 0 {
			return nil, errors.New("master playlist is empty")
		}

		sf := m3u8.MasterPlaylist[0]
		if sf.URI == "" {
			return nil, errors.New("master playlist URI is empty")
		}

		// 递归解析主播放列表指向的媒体播放列表
		resolvedURI := tool.ResolveURL(u, sf.URI)
		return FromURL(resolvedURI)
	}

	// 检查是否有任何段
	if len(m3u8.Segments) == 0 {
		return nil, errors.New("can not found any TS file description")
	}

	result := &Result{
		URL:  u,
		M3u8: m3u8,
		Keys: make(map[int]string),
	}

	for idx, key := range m3u8.Keys {
		if key == nil {
			return nil, fmt.Errorf("key at index %d is nil", idx)
		}

		switch key.Method {
		case "", CryptMethodNONE:
			continue
		case CryptMethodAES:
			// 请求URL以提取解密密钥
			keyURL := key.URI
			if keyURL == "" {
				return nil, fmt.Errorf("key URI is empty for key at index %d", idx)
			}

			resolvedKeyURL := tool.ResolveURL(u, keyURL)
			resp, err := tool.Get(resolvedKeyURL)
			if err != nil {
				return nil, fmt.Errorf("failed to request key URL '%s': %w", resolvedKeyURL, err)
			}

			// 确保resp关闭
			defer func() {
				if resp != nil {
					_ = resp.Close()
				}
			}()

			keyByte, err := io.ReadAll(resp)
			if err != nil {
				return nil, fmt.Errorf("failed to read key from URL '%s': %w", resolvedKeyURL, err)
			}

			// 检查密钥长度（AES-128密钥应为16字节）
			if len(keyByte) != 16 && len(keyByte) != 24 && len(keyByte) != 32 {
				fmt.Printf("[warning] key length is %d bytes, which is not standard AES key length (16, 24, or 32 bytes)\n", len(keyByte))
			}

			fmt.Println("decryption key: ", string(keyByte))
			result.Keys[idx] = string(keyByte)
		default:
			return nil, fmt.Errorf("unknown or unsupported cryption method: %s", key.Method)
		}
	}

	return result, nil
}
